﻿using DimensionsHelper.Client.Navigation;
using DimensionsHelper.Client.ViewModels.Message;
using DimensionsHelper.Client.ViewModels.TaskPanel;
using NavigationService = DimensionsHelper.Client.Navigation.NavigationService;

namespace DimensionsHelper.Client.ViewModels;

public partial class MainWindowViewModel : ObservableObject
{
    private readonly NavigationService _navigationService;


    private readonly IServiceProvider _serviceProvider;


    [ObservableProperty]
    private string _applicationTitle = "Dimensions Helper";


    [ObservableProperty]
    private bool _canNavigateBack;


    [ObservableProperty]
    private string _currentReportLevel = StaticSelections.ReportLevels[0];


    [ObservableProperty]
    private MessageViewModel _lastMessage;

    private TaskViewModel? _lastTask;


    [ObservableProperty]
    private IReadOnlyList<NavigationTargetData> _navigationTargets;


    [ObservableProperty]
    private NavigationTargetData? _selectedPage;

    public MainWindowViewModel(NavigationService navigationService, IServiceProvider serviceProvider)
    {
        _navigationService = navigationService;
        _serviceProvider = serviceProvider;
        _lastMessage = _serviceProvider.GetRequiredService<MessageViewModel>();
        _navigationTargets = NavigationTargetSource.Instance.NavigationTargets;
        Tasks = _serviceProvider.GetRequiredService<TaskListViewModel>();
        Tasks.RegisterLastTaskChangedHandler(OnLastTaskOfTaskListChanged);
    }


    public TaskListViewModel Tasks { get; }


    private void OnLastTaskOfTaskListChanged(TaskViewModel? viewModel)
    {
        if (_lastTask != null)
        {
            _lastTask.Messages.CollectionChanged -= OnLastTaskMessageChanged;
        }

        _lastTask = viewModel;

        if (_lastTask != null)
        {
            _lastTask.Messages.CollectionChanged += OnLastTaskMessageChanged;
        }
    }


    private void OnLastTaskMessageChanged(object? sender, NotifyCollectionChangedEventArgs e)
    {
        if (e.NewItems == null || e.NewItems.Count == 0 || e.NewItems[^1] is not MessageViewModel message)
        {
            return;
        }

        LastMessage = message;
    }


    [RelayCommand]
    private void NavigateForward()
    {
        _navigationService.NavigateForward();
    }


    [RelayCommand]
    private void NavigateBack()
    {
        _navigationService.NavigateBack();
    }


    public void UpdateCanNavigateBack()
    {
        CanNavigateBack = _navigationService.IsBackHistoryNonEmpty();
    }
    

    private static Type? GetNavigationPageType(string name, List<NavigationTargetData> targetDataList)
    {
        if (targetDataList.Count == 0 || string.IsNullOrEmpty(name))
        {
            return null;
        }

        foreach (NavigationTargetData? data in targetDataList)
        {
            if (data.Description.Equals(name, StringComparison.OrdinalIgnoreCase))
            {
                return data.PageType;
            }

            if (GetNavigationPageType(name, data.Items) is { } type)
            {
                return type;
            }
        }

        return null;
    }
}